package com.zmn.oms.zmn.business.impl.redistribute;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zmn.base.common.data.common.dro.tags.TagsDRO;
import com.zmn.base.common.data.common.query.tags.TagsQuery;
import com.zmn.base.common.data.dubbo.interfaces.tags.TagsListRemoteService;
import com.zmn.base.engineer.common.dro.foreign.engineer.ForeignEngineerDetailInfoDRO;
import com.zmn.base.engineer.dubbo.interfaces.engineer.cooperate.EngineerCooperateInfoListRemoteService;
import com.zmn.base.engineer.dubbo.interfaces.foreign.EngineerListRemoteService;
import com.zmn.base.product.common.consts.BaseProductConsts;
import com.zmn.base.product.common.dto.product.ProductBaseQuery;
import com.zmn.base.product.common.dto.product.ec.ProductBaseDRO;
import com.zmn.base.product.dubbo.interfaces.product.foreign.ProductForeignListRemoteService;
import com.zmn.common.dto2.Option;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.manager.redis.RedisManager;
import com.zmn.oms.business.interfaces.base.BaseCodeService;
import com.zmn.oms.business.interfaces.conf.distributereason.ConfOrderDistributeReasonBService;
import com.zmn.oms.business.interfaces.messageV1.common.MessageSendBaseService;
import com.zmn.oms.common.annotation.OrderWorkRedistributeLog;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.common.dto.OrderWorkRedistributeOperator;
import com.zmn.oms.common.enums.RedistributeAuditStatusEnum;
import com.zmn.oms.common.enums.RedistributeHelpStatusEnum;
import com.zmn.oms.common.enums.RedistributeStatusEnum;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.bo.conf.distribute.reason.ConfOrderDistributeReasonBO;
import com.zmn.oms.model.bo.work.redistribute.OrderWorkRedistributeApplyBO;
import com.zmn.oms.model.bo.work.redistribute.OrderWorkRedistributeAuditBO;
import com.zmn.oms.model.bo.work.redistribute.OrderWorkRedistributeModifyBO;
import com.zmn.oms.model.bo.work.redistribute.RedistributeMasterBO;
import com.zmn.oms.model.dto.messageV1.AppMessageDTO;
import com.zmn.oms.model.dto.work.masterwork.ModifyDutyTimeDTO;
import com.zmn.oms.model.entity.changerecord.OrderChangeRecord;
import com.zmn.oms.model.entity.conf.distributereason.ConfRedistributeStep;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.master.OrderMaster;
import com.zmn.oms.model.entity.masterworking.MasterWorking;
import com.zmn.oms.model.entity.redistribute.OrderWorkRedistributeApply;
import com.zmn.oms.model.entity.redistribute.OrderWorkRedistributeInfo;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.changerecord.OrderChangeRecordService;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.master.OrderMasterService;
import com.zmn.oms.services.interfaces.masterworking.MasterWorkingService;
import com.zmn.oms.services.interfaces.redistribute.OrderWorkRedistributeApplyService;
import com.zmn.oms.services.interfaces.redistribute.OrderWorkRedistributeInfoService;
import com.zmn.oms.services.interfaces.redistribute.OrderWorkRedistributeMasterService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.redistribute.OrderWorkRedistributeApplyBService;
import com.zmn.oms.zmn.business.interfaces.redistribute.OrderWorkRedistributeAuditBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkBService;
import com.zmn.oms.zmn.business.interfaces.work.customwork.ZsDistributeWorkBService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * 类描述: 工单改派申请业务实现层
 * 部分改派缘由 需特殊处理 但应产品需求 这种限制应在人在配置时做限制 不在流程中做过多的特殊处理
 * 系统首次领单超时触发改派 默认是无转单求助  无审核 直接改派
 * 品类错误和地址错误 应在配置上 默认是无求助直接到审核的
 *
 * @author: HuangChao
 * @since: 2022/05/09 13:59
 */
@Slf4j
@Service
public class OrderWorkRedistributeApplyBServiceImpl implements OrderWorkRedistributeApplyBService {

    @Autowired
    private OrderWorkRedistributeApplyService orderWorkRedistributeApplyService;
    @Autowired
    private OrderWorkRedistributeMasterService orderWorkRedistributeMasterService;
    @Autowired
    private OrderWorkRedistributeInfoService orderWorkRedistributeInfoService;
    @Autowired
    private OrderChangeRecordService orderChangeRecordService;
    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private MessageSendBaseService messageSendBaseService;
    @Autowired
    private MasterWorkingService masterWorkingService;
    @Autowired
    private ConfOrderDistributeReasonBService confOrderDistributeReasonBService;
    @Autowired
    private ZsDistributeWorkBService zsDistributeWorkBService;
    @Autowired
    private OrderMasterService orderMasterService;
    @Autowired
    private OrderWorkRedistributeAuditBService orderWorkRedistributeAuditBService;
    @Autowired
    private ZsOrderWorkBService zsOrderWorkBService;
    @Autowired
    private RedisManager redisManager;
    @Autowired
    private BaseCodeService baseCodeService;

    @DubboReference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerCooperateInfoListRemoteService engineerCooperateInfoListRemoteService;
    @DubboReference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerListRemoteService engineerListRemoteService;
    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private TagsListRemoteService tagsListRemoteService;
    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    protected ProductForeignListRemoteService productForeignListRemoteService;

    @Override
    @OrderWorkRedistributeLog(type = OrderWorkRedistributeLogConsts.ORDER_REDISTRIBUTE_LOG_TYPE_ADD_APPLY, beforeProceed = false)
    @Transactional(rollbackFor = Exception.class)
    public OrderWorkRedistributeApply addOrderWorkRedistributeApply(OrderWorkRedistributeApplyBO redistributeApplyBO) throws OmsBaseException {
        // 组装申请基本参数
        Integer waitRedistributeStatus = RedistributeStatusEnum.WAIT_REDISTRIBUTE.getCode();
        OrderWorkRedistributeApply orderWorkRedistributeApply = orderWorkRedistributeApplyService.selectByOrderIdAndWorkIdAndRedistributeStatusSrcMaster(redistributeApplyBO.getOrderId(), redistributeApplyBO.getWorkId(), waitRedistributeStatus);
        if (Objects.nonNull(orderWorkRedistributeApply)) {
            throw new OmsBaseException("存在进行中的改派申请，不可重复发起申请");
        }

        OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(redistributeApplyBO.getOrderId(), redistributeApplyBO.getWorkId());
        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            throw new OmsBaseException("工单不在进行中，请刷新列表");
        }

        if (Objects.equals(redistributeApplyBO.getApplyUserType(), GlobalConsts.OPERATE_USER_TYPE_MASTER)
                && !Objects.equals(Long.valueOf(orderWork.getMasterId()), redistributeApplyBO.getApplyUserId())) {
            throw new OmsBaseException("工单状态发生变更，请重新刷新列表");
        }

        List<TagsDRO> tagsDROList = baseCodeService.listBaseCodeMap(GlobalConsts.PLAT_MARK_ZMN, OrderConsts.BASE_CODE_MAP_ONE_TYPE_DISTRIBUTE_TIMEOUT, null, null);
        if (CollectionUtil.isNotNullOrEmpty(tagsDROList)) {
            // 派单超时限制（分钟）
            Integer timeoutLimit = tagsDROList.get(0).getTwoTypeId();
            // 预约时间
            Date dutyTime = redistributeApplyBO.getDutyTime();
            if (Objects.isNull(dutyTime)) {
                dutyTime = orderWork.getDutyTime();
            }

            // 预约时间距离当前时间的间隔（分钟）
            long intervalTime = (dutyTime.getTime() - DateUtil.getNow().getTime()) / 60 / 1000;

            // 预约时间已过时 或 距离当前时间小于【派单超时限制（分钟）】
            if (DateUtil.getNow().after(dutyTime) || timeoutLimit > intervalTime) {
                throw new OmsBaseException(String.format("预约时间已过时或已不足%d分钟，请与用户重新确定预约时间后再试，谢谢~", timeoutLimit));
            }
        }


        // 获取流程配置
        ConfOrderDistributeReasonBO conf = confOrderDistributeReasonBService.getConfOrderDistributeReasonById(redistributeApplyBO.getReasonId());
        Objects.requireNonNull(conf, "获取改派缘由失败");

        ConfRedistributeStep confRedistributeStep;
        // 非系统发起默认选择工程师配置
        if (!Objects.equals(redistributeApplyBO.getApplyUserType(), GlobalConsts.OPERATE_USER_TYPE_MASTER)) {
            confRedistributeStep = conf.getSystemRedistributeStep();
        } else {
            confRedistributeStep = conf.getEngineerRedistributeStep();
        }

        Objects.requireNonNull(confRedistributeStep, "该原因未配置改派流程");

        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(redistributeApplyBO.getOrderId());

        // 前置特殊缘由校验
        if (!Objects.equals(orderDetail.getGridCompanyId(), CompanyConsts.ZMN_JXJ_COMPANY_ID)
                && Objects.equals(redistributeApplyBO.getApplyUserType(), GlobalConsts.OPERATE_USER_TYPE_MASTER)
                && Objects.equals(redistributeApplyBO.getReasonId(), ConfDistributeReasonConsts.REASON_TYPE_NEGOTIATED_TRANSFER_ORDER)) {
            String verifyMessage = this.verifyNegotiatedTransferOrderCount(redistributeApplyBO.getApplyUserId());
            if (StringUtil.isNotBlank(verifyMessage)) {
                throw new OmsBaseException(verifyMessage);
            }
        }

        // 判断需要发起求助
        if (Objects.equals(confRedistributeStep.getHelpType(), ConfRedistributeConsts.HELP_TYPE_NONE)) {
            redistributeApplyBO.setHelpStatus(RedistributeHelpStatusEnum.NONE_HELP.getCode());
        } else {
            redistributeApplyBO.setHelpStatus(RedistributeHelpStatusEnum.PROCESSING_HELP.getCode());
        }

        redistributeApplyBO.setReason(conf.getReason());
        redistributeApplyBO.setHelpType(confRedistributeStep.getHelpType());
        redistributeApplyBO.setAuditType(confRedistributeStep.getAuditType());
        redistributeApplyBO.setRedistributeType(confRedistributeStep.getRedistributeType());
        orderWorkRedistributeApply = BeanMapper.map(redistributeApplyBO, OrderWorkRedistributeApply.class);
        orderWorkRedistributeApply.setCreater(redistributeApplyBO.getOperator());
        orderWorkRedistributeApply.setUpdater(redistributeApplyBO.getOperator());
        orderWorkRedistributeApply.setRedistributeStatus(waitRedistributeStatus);
        orderWorkRedistributeApply.setSpuriousStatus(GlobalConsts.NO);
        orderWorkRedistributeApply.setLiableType(conf.getLiableType());
        orderWorkRedistributeApply.setCountEnable(conf.getCountEnable());

        // 参数补充
        this.redistributeParamSupplement(redistributeApplyBO, orderWorkRedistributeApply, orderWork, orderDetail);

        Boolean dutyTimeChangeFlag = Boolean.FALSE;
        if (Objects.isNull(redistributeApplyBO.getDutyTime())) {
            redistributeApplyBO.setDutyTime(orderWork.getDutyTime());
            orderWorkRedistributeApply.setDutyTime(orderWork.getDutyTime());
        } else if (!Objects.equals(orderWork.getDutyTime(), redistributeApplyBO.getDutyTime())) {
            dutyTimeChangeFlag = Boolean.TRUE;
        }

        orderWorkRedistributeApply.setAuditStatus(RedistributeAuditStatusEnum.NONE_AUDIT.getCode());

        // 保存数据
        orderWorkRedistributeApplyService.insert(orderWorkRedistributeApply);
        OrderWorkRedistributeInfo orderWorkRedistributeInfo = this.getOrderWorkRedistributeInfo(orderWorkRedistributeApply, orderWork, orderDetail);
        orderWorkRedistributeInfoService.insert(orderWorkRedistributeInfo);

        // 通知工单进行中表 工单处于改派状态
        MasterWorking masterWorking = new MasterWorking();
        masterWorking.setWorkId(orderWorkRedistributeApply.getWorkId());
        masterWorking.setRedistributeStatus(GlobalConsts.NO);
        masterWorkingService.updateRedistributeStatusByKey(masterWorking);

        OrderWorkRedistributeApply finalOrderWorkRedistributeApply = orderWorkRedistributeApply;

        // 预约时间有变更 更新订单预约时间
        if (dutyTimeChangeFlag) {
            this.updateOrderDutyTime(redistributeApplyBO);
            // 预约时间有变更 取传入的预约时间去查询工程师
            orderWork.setDutyTime(redistributeApplyBO.getDutyTime());
        }
        // 特殊改派缘由处理 协商转单工程师次数记录
        if (!Objects.equals(orderDetail.getGridCompanyId(), CompanyConsts.ZMN_JXJ_COMPANY_ID)
                && Objects.equals(redistributeApplyBO.getApplyUserType(), GlobalConsts.OPERATE_USER_TYPE_MASTER)
                && Objects.equals(redistributeApplyBO.getReasonId(), ConfDistributeReasonConsts.REASON_TYPE_NEGOTIATED_TRANSFER_ORDER)) {
            this.recordMasterNegotiatedTransferOrderCount(redistributeApplyBO.getApplyUserId());
        }

        // 设置日志参数
        this.setAddApplyLogParams(redistributeApplyBO, orderWorkRedistributeApply, orderWorkRedistributeInfo, orderWork);

        // 保存申请后异步处理操作
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                try {
                    // 转单求助异步处理
                    if (!Objects.equals(redistributeApplyBO.getHelpType(), ConfRedistributeConsts.HELP_TYPE_NONE)) {
                        orderWorkRedistributeAuditBService.redistributeHelpHandle(redistributeApplyBO, orderWork, orderDetail);
                    }

                    // 无转单求助 且需审核的情况 设未待审核 并且记录日志
                    if (Objects.equals(redistributeApplyBO.getHelpType(), ConfRedistributeConsts.HELP_TYPE_NONE)
                            && !Objects.equals(redistributeApplyBO.getAuditType(), ConfRedistributeConsts.AUDIT_TYPE_NONE)) {
                        OrderWorkRedistributeAuditBO auditBO = BeanMapper.map(redistributeApplyBO, OrderWorkRedistributeAuditBO.class);
                        auditBO.setRedistributeId(finalOrderWorkRedistributeApply.getRedistributeId());
                        auditBO.setMasterSupervisorId(orderWorkRedistributeInfo.getMasterSupervisorId());
                        auditBO.setMasterSupervisorName(orderWorkRedistributeInfo.getMasterSupervisorName());
                        auditBO.setMasterId(orderWorkRedistributeInfo.getMasterId().intValue());
                        auditBO.setMasterName(orderWorkRedistributeInfo.getMasterName());
                        orderWorkRedistributeAuditBService.redistributeAuditStart(auditBO);
                    }
                } catch (Exception e) {
                    log.error("异步处理失败：{}", e.getMessage(), e);
                }
            }
        });
        return orderWorkRedistributeApply;
    }

    /**
     * 品类错误参数补充
     * @param redistributeApplyBO
     * @param orderWorkRedistributeApply
     * @param orderWork
     * @param orderDetail
     */
    @Deprecated
    private void categoryWrongSupplement(OrderWorkRedistributeApplyBO redistributeApplyBO, OrderWorkRedistributeApply orderWorkRedistributeApply, OrderWork orderWork, OrderDetail orderDetail) {
        // 默认先填充工单上的数据 修改了产品id再重新获取产品相关信息
        orderWorkRedistributeApply.setProductId(orderWork.getProductId());
        orderWorkRedistributeApply.setServCategId(orderWork.getServCategId());
        orderWorkRedistributeApply.setCategId(orderWork.getCategId());
        if (NumberUtil.isNotNullOrZero(redistributeApplyBO.getProductId())
                && !Objects.equals(redistributeApplyBO.getProductId(), orderWork.getProductId())) {
            ProductBaseDRO productBaseDRO = getProductInfo(redistributeApplyBO, orderWork);
            if (Objects.nonNull(productBaseDRO)) {
                orderWorkRedistributeApply.setProductId(productBaseDRO.getProductId());
                orderWorkRedistributeApply.setProductInfo(productBaseDRO.getProductName());
                orderWorkRedistributeApply.setServCategId(productBaseDRO.getServCategId());
                orderWorkRedistributeApply.setCategId(productBaseDRO.getCategId());
            }
        }
    }

    private ProductBaseDRO getProductInfo(OrderWorkRedistributeApplyBO redistributeApplyBO, OrderWork orderWork) {
        try {
            ProductBaseQuery query = ProductBaseQuery
                    .builder()
                    .defaultType(1)
                    .productId(redistributeApplyBO.getProductId())
                    .showType(BaseProductConsts.ERP_SHOW_TYPE)
                    .cityId(orderWork.getCityId())
                    .channelId(orderWork.getChannelId())
                    .bizType(orderWork.getBizType())
                    .build();
            ResponseDTO<List<ProductBaseDRO>> responseDTO = productForeignListRemoteService.listBaseDROByQuery(query);
            if (log.isDebugEnabled()) {
                log.debug("#getProductList 入参：{} ,出参：{}", query, responseDTO);
            }
            if (responseDTO.isSuccess() && CollectionUtil.isNotNullOrEmpty(responseDTO.getData())) {
                return responseDTO.getData().get(0);
            }
        } catch (Exception e) {
            log.error("获取产品信息失败：{}", e);
        }
        return null;
    }

    /**
     * 补充改派相关工单信息
     *
     * @param redistributeApplyBO
     * @param orderWorkRedistributeApply
     * @param orderDetail
     */
    private void redistributeParamSupplement(OrderWorkRedistributeApplyBO redistributeApplyBO, OrderWorkRedistributeApply orderWorkRedistributeApply, OrderWork orderWork, OrderDetail orderDetail) {
        /*if (Objects.equals(redistributeApplyBO.getReasonId(), ConfDistributeReasonConsts.REASON_TYPE_CATEGORY_WRONG)
                || Objects.equals(redistributeApplyBO.getReasonId(), ConfDistributeReasonConsts.REASON_TYPE_ADDRESS_WRONG)) {
            return;
        }*/
        // 品类错误数据补充
        // 默认先填充工单上的数据 修改了产品id再重新获取产品相关信息
        orderWorkRedistributeApply.setProductId(orderWork.getProductId());
        orderWorkRedistributeApply.setProductInfo(orderDetail.getProductInfo());
        orderWorkRedistributeApply.setServCategId(orderWork.getServCategId());
        orderWorkRedistributeApply.setCategId(orderWork.getCategId());
        if (Objects.equals(redistributeApplyBO.getReasonId(), ConfDistributeReasonConsts.REASON_TYPE_CATEGORY_WRONG)
                && NumberUtil.isNotNullOrZero(redistributeApplyBO.getProductId())
                && !Objects.equals(redistributeApplyBO.getProductId(), orderWork.getProductId())) {
            ProductBaseDRO productBaseDRO = getProductInfo(redistributeApplyBO, orderWork);
            if (Objects.nonNull(productBaseDRO)) {
                orderWorkRedistributeApply.setProductId(productBaseDRO.getProductId());
                orderWorkRedistributeApply.setProductInfo(productBaseDRO.getProductName());
                orderWorkRedistributeApply.setServCategId(productBaseDRO.getServCategId());
                orderWorkRedistributeApply.setCategId(productBaseDRO.getCategId());
            }
        }

        if (NumberUtil.isNullOrZero(redistributeApplyBO.getCountyId())
                || Objects.isNull(redistributeApplyBO.getLatitude()) || Objects.isNull(redistributeApplyBO.getLongitude())) {
            orderWorkRedistributeApply.setCountyId(orderDetail.getCountyId());
            orderWorkRedistributeApply.setCountyName(orderDetail.getCountyName());
            orderWorkRedistributeApply.setStreetId(orderDetail.getStreetId());
            orderWorkRedistributeApply.setStreet(orderDetail.getStreet());
            orderWorkRedistributeApply.setLatitude(orderDetail.getLatitude());
            orderWorkRedistributeApply.setLongitude(orderDetail.getLongitude());
        }

        if (StringUtil.isBlank(redistributeApplyBO.getAddress())) {
            redistributeApplyBO.setAddress(orderDetail.getAddress());
            orderWorkRedistributeApply.setAddress(orderDetail.getAddress());
        }

        if (StringUtil.isNotBlank(redistributeApplyBO.getAttachmentUrls())) {
            orderWorkRedistributeApply.setImageSrc(null);
        }
    }

    /**
     * 修改订单预约时间
     *
     * @param redistributeApplyBO
     * @throws OmsBaseException
     */
    private void updateOrderDutyTime(OrderWorkRedistributeApplyBO redistributeApplyBO) throws OmsBaseException {
        ModifyDutyTimeDTO modifyDutyTimeDTO = new ModifyDutyTimeDTO();
        modifyDutyTimeDTO.setOrderId(redistributeApplyBO.getOrderId());
        modifyDutyTimeDTO.setWorkId(redistributeApplyBO.getWorkId());
        modifyDutyTimeDTO.setDutyTime(redistributeApplyBO.getDutyTime());
        modifyDutyTimeDTO.setOperatorId(redistributeApplyBO.getOperatorId());
        modifyDutyTimeDTO.setOperator(redistributeApplyBO.getOperator());
        modifyDutyTimeDTO.setOperatorType(redistributeApplyBO.getOperatorType());
        modifyDutyTimeDTO.setOperateTime(redistributeApplyBO.getOperateTime());
        zsOrderWorkBService.updateOrderDutyTime(modifyDutyTimeDTO);
    }

    @Override
    @OrderWorkRedistributeLog(type = OrderWorkRedistributeLogConsts.ORDER_REDISTRIBUTE_LOG_TYPE_ADD_APPLY, beforeProceed = false)
    @Transactional(rollbackFor = Exception.class)
    public OrderWorkRedistributeApply autoRedistributeApply(OrderWorkRedistributeApplyBO applyBO) throws OmsBaseException {
        if (NumberUtil.isNullOrZero(applyBO.getWorkId())) {
            applyBO.setWorkId(applyBO.getOrderId());
        }
        OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(applyBO.getOrderId(), applyBO.getWorkId());
        if (Objects.nonNull(orderWork) && !Objects.equals(orderWork.getDistributeWay(), OrderDistributeConsts.DISTRIBUTE_WAY_PLAT)) {
            throw new OmsBaseException("非平台直派不做处理");
        }

        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            throw new OmsBaseException("工单不在进行中，不处理");
        }

        OrderChangeRecord record = orderChangeRecordService.getChangeRecordByOrderId(applyBO.getOrderId());
        if (Objects.nonNull(record) && NumberUtil.isNotNullOrZero(record.getDistributeCount())) {
            throw new OmsBaseException("非首次派单不处理");
        }
        // 查询改派缘由 系统发起的 写死id
        ConfOrderDistributeReasonBO conf = confOrderDistributeReasonBService.getConfOrderDistributeReasonById(ConfDistributeReasonConsts.REASON_TYPE_SYSTEM_AUTO_APPLY);
        if (StringUtil.isBlank(conf.getOrderType()) || !conf.getOrderType().contains(orderWork.getType().toString())) {
            throw new OmsBaseException("该订单类型不发起自动改派");
        }

        Integer waitRedistributeStatus = RedistributeStatusEnum.WAIT_REDISTRIBUTE.getCode();
        OrderWorkRedistributeApply orderWorkRedistributeApply = orderWorkRedistributeApplyService.selectByOrderIdAndWorkIdAndRedistributeStatusSrcMaster(applyBO.getOrderId(), applyBO.getWorkId(), waitRedistributeStatus);
        if (Objects.nonNull(orderWorkRedistributeApply)) {
            throw new OmsBaseException("存在进行中的改派申请，不可重复发起申请");
        }

        ConfRedistributeStep systemRedistributeStepConf = conf.getSystemRedistributeStep();
        if (Objects.isNull(systemRedistributeStepConf)) {
            throw new OmsBaseException("未配置系统自动发起改派流程");
        }

        OrderDetail detail = orderDetailService.findOrderDetailByKey(applyBO.getOrderId());
        applyBO.setDutyTime(orderWork.getDutyTime());
        BeanMapper.copy(detail, applyBO);
        BeanMapper.copy(systemRedistributeStepConf, applyBO);
        orderWorkRedistributeApply = new OrderWorkRedistributeApply();
        BeanMapper.copy(applyBO, orderWorkRedistributeApply);
        orderWorkRedistributeApply.setReasonId(ConfDistributeReasonConsts.REASON_TYPE_SYSTEM_AUTO_APPLY);
        orderWorkRedistributeApply.setReason(conf.getReason());

        // 判断需要发起求助
        if (Objects.equals(systemRedistributeStepConf.getHelpType(), ConfRedistributeConsts.HELP_TYPE_NONE)) {
            orderWorkRedistributeApply.setHelpStatus(RedistributeHelpStatusEnum.NONE_HELP.getCode());
        } else {
            orderWorkRedistributeApply.setHelpStatus(RedistributeHelpStatusEnum.PROCESSING_HELP.getCode());
        }

        orderWorkRedistributeApply.setRedistributeStatus(RedistributeStatusEnum.WAIT_REDISTRIBUTE.getCode());
        orderWorkRedistributeApply.setAuditStatus(RedistributeAuditStatusEnum.NONE_AUDIT.getCode());
        orderWorkRedistributeApply.setApplyUserId(Long.valueOf(GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
        orderWorkRedistributeApply.setApplyUser(ConfRedistributeConsts.getApplyTypeName(ConfRedistributeConsts.REDISTRIBUTE_APPLY_TYPE_SYSTEM));
        orderWorkRedistributeApply.setApplyUserType(ConfRedistributeConsts.REDISTRIBUTE_APPLY_TYPE_SYSTEM);
        orderWorkRedistributeApply.setCreater(GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
        orderWorkRedistributeApply.setUpdater(GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
        orderWorkRedistributeApply.setRedistributeStatus(waitRedistributeStatus);
        orderWorkRedistributeApply.setSpuriousStatus(GlobalConsts.NO);
        orderWorkRedistributeApply.setLiableType(conf.getLiableType());
        orderWorkRedistributeApply.setCountEnable(conf.getCountEnable());

        orderWorkRedistributeApplyService.insert(orderWorkRedistributeApply);
        OrderWorkRedistributeInfo orderWorkRedistributeInfo = this.getOrderWorkRedistributeInfo(orderWorkRedistributeApply, orderWork, detail);
        orderWorkRedistributeInfoService.insert(orderWorkRedistributeInfo);

        OrderWorkRedistributeApply finalOrderWorkRedistributeApply = orderWorkRedistributeApply;
        /*if (Objects.equals(orderWorkRedistributeApply.getHelpType(), ConfRedistributeConsts.HELP_TYPE_RANGE)) {
            // 调用获取派单接口获取工程师集合
            List<ZsOrderDistributeVO> zsOrderDistributeVOList = zsDistributeWorkBService.getRedistributeMasterList(orderWork, detail);
            if (CollectionUtil.isNotNullOrEmpty(zsOrderDistributeVOList)) {
                List<RedistributeMasterBO> redistributeMasterList = zsOrderDistributeVOList.stream()
                        .map(m -> BeanMapper.map(m, RedistributeMasterBO.class))
                        .filter(r -> !Objects.equals(r.getMasterId(), orderWork.getMasterId()))
                        .collect(Collectors.toList());

                if (CollectionUtil.isNotNullOrEmpty(redistributeMasterList)) {
                    List<OrderWorkRedistributeMaster> orderWorkRedistributeMasterList = redistributeMasterList.stream().map(redistributeMasterBO -> {
                        OrderWorkRedistributeMaster orderWorkRedistributeMaster = BeanMapper.map(finalOrderWorkRedistributeApply, OrderWorkRedistributeMaster.class);
                        BeanMapper.copy(redistributeMasterBO, orderWorkRedistributeMaster);
                        orderWorkRedistributeMaster.setStatus(GlobalConsts.YES);
                        return orderWorkRedistributeMaster;
                    }).collect(Collectors.toList());

                    // 保存可领单工程师数据
                    orderWorkRedistributeMasterService.batchInsert(orderWorkRedistributeMasterList);

                    // 通知工程师有转单求助
                    this.pushRedistributeHelpAppMsg(redistributeMasterList, orderWorkRedistributeApply, orderWork, detail);
                }
            }
        }*/

        // 2、通知工单进行中表 工单处于改派中状态
        MasterWorking masterWorking = new MasterWorking();
        masterWorking.setWorkId(orderWorkRedistributeApply.getWorkId());
        masterWorking.setRedistributeStatus(GlobalConsts.NO);
        masterWorkingService.updateRedistributeStatusByKey(masterWorking);

        // 3、设置日志参数
        this.setAddApplyLogParams(applyBO, orderWorkRedistributeApply, orderWorkRedistributeInfo, orderWork);

        // 4、保存申请后异步处理操作
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                try {
                    // 转单求助流程处理
                    if (Objects.equals(applyBO.getHelpType(), ConfRedistributeConsts.HELP_TYPE_RANGE)) {
                        orderWorkRedistributeAuditBService.redistributeHelpHandle(applyBO, orderWork, detail);
                    }

                    // 无转单求助 且需审核的情况 设未待审核 并且记录日志
                    if (Objects.equals(systemRedistributeStepConf.getHelpType(), ConfRedistributeConsts.HELP_TYPE_NONE)
                            && !Objects.equals(systemRedistributeStepConf.getAuditType(), ConfRedistributeConsts.AUDIT_TYPE_NONE)) {
                        OrderWorkRedistributeAuditBO auditBO = BeanMapper.map(finalOrderWorkRedistributeApply, OrderWorkRedistributeAuditBO.class);
                        BeanMapper.copy(applyBO, auditBO);
                        auditBO.setMasterSupervisorId(orderWorkRedistributeInfo.getMasterSupervisorId());
                        auditBO.setMasterSupervisorName(orderWorkRedistributeInfo.getMasterSupervisorName());
                        auditBO.setMasterId(orderWorkRedistributeInfo.getMasterId().intValue());
                        auditBO.setMasterName(orderWorkRedistributeInfo.getMasterName());
                        orderWorkRedistributeAuditBService.redistributeAuditStart(auditBO);
                    }
                } catch (Exception e) {
                    log.error("异步处理失败：{}", e);
                }
            }
        });
        return orderWorkRedistributeApply;
    }

    @Override
    @OrderWorkRedistributeLog(type = OrderWorkRedistributeLogConsts.ORDER_REDISTRIBUTE_LOG_TYPE_CANCEL, beforeProceed = false)
    @Transactional(rollbackFor = Exception.class)
    public void autoCancelRedistributeApply(OrderWorkRedistributeOperator orderWorkRedistributeOperator) throws OmsBaseException {
        log.debug("改派申请自动取消，OrderWorkRedistributeOperator={}", JSON.toJSONString(orderWorkRedistributeOperator));

        OrderWorkRedistributeApply orderWorkRedistributeApply = orderWorkRedistributeApplyService.selectByOrderIdAndWorkIdAndRedistributeStatusSrcMaster(orderWorkRedistributeOperator.getOrderId(), orderWorkRedistributeOperator.getWorkId(), RedistributeStatusEnum.WAIT_REDISTRIBUTE.getCode());
        if (Objects.isNull(orderWorkRedistributeApply)) {
            throw new OmsBaseException(String.format("订单ID：[%d]，无对应进行中的申请，不处理", orderWorkRedistributeOperator.getOrderId()));
        }

        orderWorkRedistributeOperator.setRedistributeId(orderWorkRedistributeApply.getRedistributeId());

        // 更新数据
        OrderWorkRedistributeApply redistributeApply = new OrderWorkRedistributeApply();

        // 处理中和待审核，都要迁移到审核失效
        if (Objects.equals(orderWorkRedistributeApply.getAuditStatus(), RedistributeAuditStatusEnum.WAIT_AUDIT.getCode())
                || Objects.equals(orderWorkRedistributeApply.getAuditStatus(), RedistributeAuditStatusEnum.PROCESSING_AUDIT.getCode())) {
            redistributeApply.setAuditStatus(RedistributeAuditStatusEnum.INVALID_AUDIT.getCode());
        }

        // 若是待求助，则塞求助失败
        if (Objects.equals(orderWorkRedistributeApply.getHelpStatus(), RedistributeHelpStatusEnum.PROCESSING_HELP.getCode())) {
            redistributeApply.setHelpStatus(RedistributeHelpStatusEnum.HELP_FAILED.getCode());
        }

        redistributeApply.setRedistributeId(orderWorkRedistributeOperator.getRedistributeId());
        redistributeApply.setRedistributeStatus(RedistributeStatusEnum.CANCEL_REDISTRIBUTE.getCode());
        redistributeApply.setUpdater(orderWorkRedistributeOperator.getOperator());
        redistributeApply.setUpdateTime(DateUtil.getNow());
        orderWorkRedistributeApplyService.updateByPrimaryKeySelective(redistributeApply);
        orderWorkRedistributeMasterService.updateStatusByRedistributeId(redistributeApply.getRedistributeId(), GlobalConsts.NO);

        // 更新工单进行中表状态
        MasterWorking masterWorking = new MasterWorking();
        masterWorking.setWorkId(orderWorkRedistributeOperator.getWorkId());
        masterWorking.setRedistributeStatus(GlobalConsts.NONE);
        masterWorkingService.updateRedistributeStatusByKey(masterWorking);
    }

    @Override
    @OrderWorkRedistributeLog(type = OrderWorkRedistributeLogConsts.ORDER_REDISTRIBUTE_LOG_TYPE_CANCEL)
    @Transactional(rollbackFor = Exception.class)
    public void cancelRedistributeApply(OrderWorkRedistributeModifyBO cancelBO) throws OmsBaseException {
        // 1、校验
        OrderWorkRedistributeApply orderWorkRedistributeApply = orderWorkRedistributeApplyService.selectByKeySrcMaster(cancelBO.getRedistributeId());
        if (Objects.isNull(orderWorkRedistributeApply) || !Objects.equals(orderWorkRedistributeApply.getRedistributeStatus(), RedistributeStatusEnum.WAIT_REDISTRIBUTE.getCode())) {
            throw new OmsBaseException("该改派申请不存在或已完结！");
        }

        // 2、更新改派申请数据

        // 处理中和待审核，都要迁移到审核失效
        if (Objects.equals(orderWorkRedistributeApply.getAuditStatus(), RedistributeAuditStatusEnum.WAIT_AUDIT.getCode())
                || Objects.equals(orderWorkRedistributeApply.getAuditStatus(), RedistributeAuditStatusEnum.PROCESSING_AUDIT.getCode())) {
            orderWorkRedistributeApply.setAuditStatus(RedistributeAuditStatusEnum.INVALID_AUDIT.getCode());
        }

        // 若是待求助，则塞求助失败
        if (Objects.equals(orderWorkRedistributeApply.getHelpStatus(), RedistributeHelpStatusEnum.PROCESSING_HELP.getCode())) {
            orderWorkRedistributeApply.setHelpStatus(RedistributeHelpStatusEnum.HELP_FAILED.getCode());
        }

        orderWorkRedistributeApply.setAuditStatus(RedistributeAuditStatusEnum.NONE_AUDIT.getCode());
        orderWorkRedistributeApply.setRedistributeStatus(RedistributeStatusEnum.CANCEL_REDISTRIBUTE.getCode());
        orderWorkRedistributeApply.setUpdater(cancelBO.getOperator());
        orderWorkRedistributeApply.setUpdateTime(DateUtil.getNow());
        orderWorkRedistributeApplyService.updateByPrimaryKeySelective(orderWorkRedistributeApply);
        orderWorkRedistributeMasterService.updateStatusByRedistributeId(orderWorkRedistributeApply.getRedistributeId(), GlobalConsts.NO);

        // 3、更新工单进行中表状态
        MasterWorking masterWorking = new MasterWorking();
        masterWorking.setWorkId(orderWorkRedistributeApply.getWorkId());
        masterWorking.setRedistributeStatus(GlobalConsts.NONE);
        masterWorkingService.updateRedistributeStatusByKey(masterWorking);
    }

    @Override
    @OrderWorkRedistributeLog(type = OrderWorkRedistributeLogConsts.ORDER_REDISTRIBUTE_LOG_TYPE_HELP_TAKE, beforeProceed = false)
    @Transactional(rollbackFor = Exception.class)
    public void redistributeTake(OrderWorkRedistributeModifyBO takeBO) {
        OrderWorkRedistributeApply orderWorkRedistributeApply = new OrderWorkRedistributeApply();
        orderWorkRedistributeApply.setRedistributeId(takeBO.getRedistributeId());
        orderWorkRedistributeApply.setRedistributeStatus(RedistributeStatusEnum.REDISTRIBUTE_SUCCESS.getCode());
        orderWorkRedistributeApply.setHelpStatus(RedistributeHelpStatusEnum.HELP_SUCCESS.getCode());
        orderWorkRedistributeApply.setRedistributeMasterId(takeBO.getMasterId());
        orderWorkRedistributeApply.setRedistributeMasterName(takeBO.getMasterName());
        orderWorkRedistributeApply.setDistributeGrid(takeBO.getDistributeGrid());
        orderWorkRedistributeApply.setUpdater(takeBO.getMasterName());
        orderWorkRedistributeApply.setUpdateTime(DateUtil.getNow());
        orderWorkRedistributeApplyService.updateByPrimaryKeySelective(orderWorkRedistributeApply);
        // 改派成功取消抢单
        orderWorkRedistributeMasterService.updateStatusByRedistributeId(takeBO.getRedistributeId(), GlobalConsts.NO);

        // 更新工单进行中表状态
        MasterWorking masterWorking = new MasterWorking();
        masterWorking.setWorkId(takeBO.getWorkId());
        masterWorking.setRedistributeStatus(GlobalConsts.YES);
        masterWorkingService.updateRedistributeStatusByKey(masterWorking);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderWorkRedistributeApply redistributeHelpTimeout(OrderWorkRedistributeModifyBO modifyBO) throws OmsBaseException {
        // 1、校验
        if (Objects.isNull(modifyBO.getWorkId())) {
            modifyBO.setWorkId(modifyBO.getOrderId());
        }
        OrderWorkRedistributeApply orderWorkRedistributeApply = orderWorkRedistributeApplyService.selectByKeySrcMaster(modifyBO.getRedistributeId());
        if (Objects.isNull(orderWorkRedistributeApply) || !Objects.equals(orderWorkRedistributeApply.getRedistributeStatus(), RedistributeStatusEnum.WAIT_REDISTRIBUTE.getCode())) {
            log.info("改派申请：{} 对应改派申请不存在或已完结！", modifyBO.getRedistributeId());
            return orderWorkRedistributeApply;
        }

        // 2、数据处理
        orderWorkRedistributeApply.setHelpTimeoutStatus(GlobalConsts.YES);
        orderWorkRedistributeApply.setHelpStatus(RedistributeHelpStatusEnum.HELP_FAILED.getCode());
        orderWorkRedistributeApply.setUpdater(GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
        orderWorkRedistributeApply.setUpdateTime(DateUtil.getNow());
        orderWorkRedistributeApplyService.updateByPrimaryKeySelective(orderWorkRedistributeApply);
        orderWorkRedistributeMasterService.updateStatusByRedistributeId(orderWorkRedistributeApply.getRedistributeId(), GlobalConsts.NO);

        // 3、更新成功后 异步处理其他操作
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                try {
                    // 审核流程处理
                    if (!Objects.equals(orderWorkRedistributeApply.getAuditType(), ConfRedistributeConsts.AUDIT_TYPE_NONE)
                            && Objects.equals(orderWorkRedistributeApply.getAuditStatus(), RedistributeAuditStatusEnum.NONE_AUDIT.getCode())) {
                        OrderWorkRedistributeAuditBO auditBO = BeanMapper.map(orderWorkRedistributeApply, OrderWorkRedistributeAuditBO.class);
                        BeanMapper.copy(modifyBO, auditBO);
                        OrderWorkRedistributeInfo orderWorkRedistributeInfo = orderWorkRedistributeInfoService.findRedistributeInfoById(modifyBO.getRedistributeId());
                        auditBO.setApplyUserId(orderWorkRedistributeApply.getApplyUserId());
                        auditBO.setApplyUser(orderWorkRedistributeApply.getApplyUser());
                        auditBO.setApplyUserType(orderWorkRedistributeApply.getApplyUserType());
                        auditBO.setMasterSupervisorId(orderWorkRedistributeInfo.getMasterSupervisorId());
                        auditBO.setMasterSupervisorName(orderWorkRedistributeInfo.getMasterSupervisorName());
                        auditBO.setMasterId(orderWorkRedistributeInfo.getMasterId().intValue());
                        auditBO.setMasterName(orderWorkRedistributeInfo.getMasterName());
                        orderWorkRedistributeAuditBService.redistributeAuditStart(auditBO);
                    }
                } catch (Exception e) {
                    log.error("异步处理失败：{}", e);
                }
            }
        });
        return orderWorkRedistributeApply;
    }


    /**
     * 获取发起改派申请时的工单快照信息
     *
     * @param orderWorkRedistributeApply
     * @param orderDetail
     * @return
     */
    private OrderWorkRedistributeInfo getOrderWorkRedistributeInfo(OrderWorkRedistributeApply orderWorkRedistributeApply, OrderWork orderWork, OrderDetail orderDetail) throws OmsBaseException {
        if (Objects.isNull(orderWork) || Objects.isNull(orderDetail)) {
            throw new OmsBaseException("获取工单快照信息失败");
        }

        List<OrderMaster> masters = orderMasterService.listMasterByWorkId(orderWork.getOrderId(), orderWork.getWorkId(), OrderConsts.ORDER_MASTER_TYPE_MAIN);
        if (CollectionUtil.isNullOrEmpty(masters)) {
            throw new OmsBaseException("工程师信息查询失败");
        }
        OrderMaster orderMaster = masters.get(0);
        OrderWorkRedistributeInfo orderWorkRedistributeInfo = new OrderWorkRedistributeInfo();
        orderWorkRedistributeInfo.setRedistributeId(orderWorkRedistributeApply.getRedistributeId());
        orderWorkRedistributeInfo.setMasterPhone(orderMaster.getMasterPhone());

        // 设置工程师产品分组
        if (Objects.nonNull(orderMaster.getMasterId())) {
            log.info("getOrderWorkRedistributeInfo#getProductGroupByEngineerIdAndBizType 入参 [{}] [{}]",orderMaster.getMasterId(),orderWork.getBizType());
            ResponseDTO<Option<Integer>> responseDTO = engineerCooperateInfoListRemoteService.getProductGroupByEngineerIdAndBizType(orderMaster.getMasterId(), orderWork.getBizType());
            log.info("getOrderWorkRedistributeInfo#getProductGroupByEngineerIdAndBizType 出参 [{}]",JSON.toJSONString(responseDTO));
            if (responseDTO.isSuccess() && Objects.nonNull(responseDTO.getData())) {
                orderWorkRedistributeInfo.setMasterGroupName(StringUtils.defaultString(responseDTO.getData().getLabel()));
            }
        }

        BeanMapper.copy(orderWork, orderWorkRedistributeInfo);
        BeanMapper.copy(orderDetail, orderWorkRedistributeInfo);
        orderWorkRedistributeInfo.setCreater(orderWorkRedistributeApply.getCreater());
        orderWorkRedistributeInfo.setUpdater(orderWorkRedistributeApply.getUpdater());
        orderWorkRedistributeInfo.setCreateTime(DateUtil.getNow());
        orderWorkRedistributeInfo.setUpdateTime(DateUtil.getNow());
        return orderWorkRedistributeInfo;
    }

    /**
     * 发送转单求助信息
     *
     * @param redistributeMasterList
     * @param orderWork
     */
    private void pushRedistributeHelpAppMsg(List<RedistributeMasterBO> redistributeMasterList, OrderWorkRedistributeApply orderWorkRedistributeApply, OrderWork orderWork, OrderDetail orderDetail) {
        log.info("#pushRedistributeHelpAppMsg:{}", JSON.toJSONString(redistributeMasterList));
        if (CollectionUtil.isNullOrEmpty(redistributeMasterList)) {
            return;
        }
        String productInfo = orderWorkRedistributeApply.getProductInfo();
        if (StringUtil.isBlank(productInfo)) {
            productInfo = orderDetail.getProductInfo();
        }
        JSONObject params = new JSONObject();
        params.put("product_name", productInfo);
        params.put("reason", orderWorkRedistributeApply.getReason());
        params.put("redistribute_id", orderWorkRedistributeApply.getRedistributeId());
        params.put("order_id", orderWork.getOrderId());
        params.put("work_id", orderWork.getWorkId());
        // 发送消息通知
        List<Integer> masterIdList = redistributeMasterList.stream().map(RedistributeMasterBO::getMasterId).collect(Collectors.toList());
        AppMessageDTO appMessageDTO = AppMessageDTO.builder()
                .orderId(orderWork.getOrderId())
                .plat(orderWork.getPlatWork())
                .masterIdList(masterIdList)
                .ruleId(MessageConsts.ZMN_MSG_RULEID_HELP_ORDER)
                .ruleCode(MessageConsts.ZMN_MSG_RULE_CODE_HELP_ORDER)
                .params(params.toJSONString())
                .build();
        messageSendBaseService.batchSendAndroidAndIOSMessage(appMessageDTO);

    }

    /**
     * 校验工程师发起协商转单次数
     * @param applyUserId
     */
    private String verifyNegotiatedTransferOrderCount(Long applyUserId) {
        TagsQuery tagsDIO = new TagsQuery();
        tagsDIO.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        tagsDIO.setOneTypeId(1202);
        ResponseDTO<List<TagsDRO>> codeMapRemote = tagsListRemoteService.listByTagsDIO(tagsDIO);
        if (!codeMapRemote.isSuccess()) {
            return "查询工程师协商转单配置失败，请稍后重试！";
        }
        if (CollectionUtil.isNullOrEmpty(codeMapRemote.getData())) {
            return "无法获取工程师协商转单次数配置，请稍后重试！";
        }

        Integer confCount = codeMapRemote.getData().get(0).getTwoTypeId();
        // 获取工程师当天协商转单次数
        String redisKey = String.format(RedisKeyConsts.MASTER_NEGOTIATED_TRANSFER_ORDER_COUNT_KEY, applyUserId);
        String countStr = redisManager.get(redisKey);
        Integer count = 0;
        if (StringUtil.isNotBlank(countStr)) {
            count = Integer.valueOf(countStr);
        }

        if (count >= confCount) {
            return "协商转单次数超限，请选择其他缘由！";
        }
        return null;
    }

    /**
     * 记录工程师发起协商转单次数
     * @param applyUserId
     */
    private void recordMasterNegotiatedTransferOrderCount(Long applyUserId) {
        String redisKey = String.format(RedisKeyConsts.MASTER_NEGOTIATED_TRANSFER_ORDER_COUNT_KEY, applyUserId);
        if (!redisManager.exists(redisKey)) {
            // 离散该数据，推迟至12点后的5分钟内，防止大量过期导致redis阻塞
            redisManager.incr(redisKey);

            // 今天夜晚0点
            Date dateEnd = DateUtil.getDateEnd(DateUtil.getNow());

            // 今天夜晚0点时间 单位：秒
            long seconds = (dateEnd.getTime() - DateUtil.getNowTimestampMillis()) / 1000;

            // 偏移量
            int offset = new Random().nextInt(300);

            redisManager.expire(redisKey, ((Long) (seconds + offset)).intValue());
        } else {
            redisManager.incr(redisKey);
        }
    }

    /**
     * 设置发起改派申请日志参数
     *
     * @param redistributeApplyBO
     * @param orderWorkRedistributeApply
     * @param orderWorkRedistributeInfo
     */
    private void setAddApplyLogParams(OrderWorkRedistributeApplyBO redistributeApplyBO, OrderWorkRedistributeApply orderWorkRedistributeApply, OrderWorkRedistributeInfo orderWorkRedistributeInfo, OrderWork orderWork) {

        redistributeApplyBO.setRedistributeOperatorLogRemark("");
        redistributeApplyBO.setRedistributeId(orderWorkRedistributeApply.getRedistributeId());
        StringBuilder sb = new StringBuilder();
        if (Objects.equals(orderWorkRedistributeApply.getHelpType(), ConfRedistributeConsts.HELP_TYPE_SPECIFY)) {
            // 查询工程师信息
            ResponseDTO<ForeignEngineerDetailInfoDRO> cacheEngineerByEngineerId = engineerListRemoteService.getEngineerDetailById(redistributeApplyBO.getHelpMasterId());
            ForeignEngineerDetailInfoDRO baseEngineerDRO = cacheEngineerByEngineerId.getData();
            if (cacheEngineerByEngineerId.isSuccess() && Objects.nonNull(baseEngineerDRO)) {
                //查询工程师分组信息
                String masterGroupName = null;
//                log.info("setAddApplyLogParams#getProductGroupByEngineerIdAndBizType 入参 [{}] [{}]",orderWorkRedistributeInfo.getMasterId().intValue(),orderWork.getBizType());
                ResponseDTO<Option<Integer>> responseDTO = engineerCooperateInfoListRemoteService.getProductGroupByEngineerIdAndBizType(
                        orderWorkRedistributeInfo.getMasterId().intValue(), orderWork.getBizType());
                log.info("setAddApplyLogParams#getProductGroupByEngineerIdAndBizType 出参 [{}]", responseDTO);
                if (responseDTO.isSuccess()) {
                    masterGroupName = (StringUtils.defaultString(responseDTO.getData().getLabel()));
                }
                sb.append(orderWorkRedistributeInfo.getMasterName()).append("->");
                if (StringUtil.isNotBlank(masterGroupName)) {
                    sb.append(masterGroupName).append("-").append(redistributeApplyBO.getHelpMasterName());
                }

                // 平台直派
                if (Objects.equals(orderWork.getDistributeWay(), OrderDistributeConsts.DISTRIBUTE_WAY_PLAT)) {
                    // 工程师后缀
                    if (Objects.equals(baseEngineerDRO.getCooperationType(), GlobalConsts.NO)) {
                        sb.append("[直营]");
                    } else {
                        sb.append("[非直营]");
                    }
                }
                sb.append("\n");
            }
        }
        sb.append("改派缘由：" + orderWorkRedistributeApply.getReason());

        // 在改派日志中，若缘由为【用户来电申请改派】，则展示所选中的跟单内容-缘由
        if(Objects.equals(orderWorkRedistributeApply.getReasonId(), ConfDistributeReasonConsts.REASON_TYPE_USER_CALL_TO_APPLY)){
            sb.append(String.format("（%s - %s）", redistributeApplyBO.getTrackContent(), redistributeApplyBO.getTrackReasonName()));
        }

        if (StringUtil.isNotBlank(orderWorkRedistributeApply.getApplyRemark())) {
            sb.append("\n备注：");
            sb.append(orderWorkRedistributeApply.getApplyRemark());
        }
        redistributeApplyBO.setRedistributeOperatorLogRemark(sb.toString());
    }
}
